﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using LuckyLoot.ServiceFacade.Implementation;
using LuckyLoot.Common;
using LuckyLoot.ServiceFacade.Contracts;
using LuckyLoot.Presentation.BasePage;
using LuckyLoot.Common.Validation;
using LuckyLoot.Domain.Entities;

namespace LuckyLoot.Presentation
{
    public partial class SupplyPage : LuckyLootPage
    {
        private const string QueryStringSupplyID = "SupplyID";

        private ISupplyManagementService _supplyService;
        public ISupplyManagementService SupplyService
        {
            get
            {
                if (_supplyService == null)
                    _supplyService = new SupplyManagementService();

                return _supplyService;
            }
        }

        public int SupplyID
        {
            set
            {
                this.ViewState[QueryStringSupplyID] = value;
            }
            get
            {
                int viewStateTypedSupplyID;

                if (this.ViewState[QueryStringSupplyID] != null)
                {
                    if (Int32.TryParse(this.ViewState[QueryStringSupplyID].ToString(), out viewStateTypedSupplyID))
                        return viewStateTypedSupplyID;
                }

                return 0;
            }
        }

        public bool HasSelectedRecord
        {
            get
            {
                return SupplyID > 0;
            }
        }

        private void SetCommandsVisibility()
        {

        }

        private void SelectRecord(string id)
        {
            if (!string.IsNullOrWhiteSpace(id))
            {
                int intID;
                if (Int32.TryParse(id, out intID))
                    SelectRecord(intID);
            }
        }

        private void SelectRecord(int id)
        {
            ValidState.Requires<ArgumentException>(id > 0);
            var supply = this.SupplyService.GetSupply(id);

            SelectRecord(supply);
        }

        private void SelectRecord(LuckyLoot.Domain.Entities.Supply supply)
        {
            this.supplyName.Text = supply.Name;
            this.supplyDescription.Text = supply.Description;
            this.supplyAcquisitionDate.Text = supply.Acquisition.ToString();
            this.supplyExpirationDate.Text = supply.Expiration.HasValue ? supply.Expiration.Value.ToString() : string.Empty;
            this.supplyAmount.Text = supply.Amount.ToString();
            this.supplyContentAmount.Text = supply.ContentAmount.ToString();
            this.supplyType.SelectedValue = ((int)supply.Type).ToString();
            this.supplyMeasureType.SelectedValue = ((int)supply.MeasureType).ToString();

            this.SupplyID = supply.Id;
        }

        private void ClearRecordSelection()
        {
            this.SupplyID = 0;
            this.ClearFields();
        }

        private void ClearFields()
        {
            this.supplyName.Text = string.Empty;
            this.supplyDescription.Text = string.Empty;
            this.supplyAcquisitionDate.Text = string.Empty;
            this.supplyExpirationDate.Text = string.Empty;
            this.supplyAmount.Text = string.Empty;
            this.supplyContentAmount.Text = string.Empty;
            this.supplyType.SelectedIndex = 0;
            this.supplyMeasureType.SelectedIndex = 0;
        }


        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                this.BindSupplyTypes();
                this.BindMeasureTypes();

                if (!Page.IsPostBack)
                {
                    var supplyIDString = HttpContext.Current.Request.QueryString[QueryStringSupplyID];
                    this.SelectRecord(supplyIDString);
                }

                this.SaveSupply.Click += new EventHandler(SaveSupplyClick);
                this.SetCommandsVisibility();
                this.BindGrid();
            }
            catch (Exception ex)
            {
                MasterPage.ShowErrorMessage(ex.Message);
            }
        }

        private void BindGrid()
        {
            var supplies = this.SupplyService.GetAllSupplies();

            if (supplies.Count() > 0)
            {
                this.suppliesGrid.DataSource = supplies;
                this.suppliesGrid.DataBind();
                this.suppliesGrid.Visible = true;
                this.suppliesLabel.Visible = true;
            }
        }

        public void SaveSupplyClick(object sender, EventArgs e)
        {
            DateTime acquisition;
            if (!DateTime.TryParse(supplyAcquisitionDate.Text, out acquisition))
                throw new ArgumentException("Não foi possível converter em uma Data o valor informado no campo Aquisição.");

            DateTime? expiration = null;
            if (!string.IsNullOrWhiteSpace(supplyExpirationDate.Text))
            {
                DateTime parsedDate;
                if (DateTime.TryParse(supplyExpirationDate.Text, out parsedDate))
                    expiration = parsedDate;
            }

            int amount;
            if (!Int32.TryParse(supplyAmount.Text, out amount))
                throw new ArgumentException("Não foi possível converter em um número o valor informado no campo Quantidade (de embalagens).");

            int contentAmount;
            if (!Int32.TryParse(supplyContentAmount.Text, out contentAmount))
                throw new ArgumentException("Não foi possível converter em um número o valor informado no campo Quantidade (de unidades por embalagem).");
            
            int supplyParsedType;
            if (!Int32.TryParse(supplyType.Text, out supplyParsedType))
                throw new ArgumentException("Não foi possível converter em um número o valor informado no campo Tipo de material.");
            
            int supplyMeasure;
            if (!Int32.TryParse(supplyMeasureType.Text, out supplyMeasure))
                throw new ArgumentException("Não foi possível converter em um número o valor informado no campo Unidade de medida.");


            Supply supply;
            if (this.HasSelectedRecord)
                supply = this.SupplyService.UpdateSupply(SupplyID, supplyName.Text, supplyDescription.Text, acquisition, expiration, amount, contentAmount, supplyParsedType, supplyMeasure);
            else
                supply = this.SupplyService.CreateSupply(supplyName.Text, supplyDescription.Text, acquisition, expiration, amount, contentAmount, supplyParsedType, supplyMeasure);

            this.SelectRecord(supply);
            this.SetCommandsVisibility();
            MasterPage.ShowSuccessMessage("Material salvo com sucesso!");
            this.BindGrid();
        }


        private void BindSupplyTypes()
        { 
            Array values = Enum.GetValues(typeof(SupplyType));

            foreach(SupplyType val in values )
            {
                this.supplyType.Items.Add(new ListItem(val.GetDescription(), ((int)val).ToString()));
            }
        }

        private void BindMeasureTypes()
        {
            Array values = Enum.GetValues(typeof(MeasureType));

            foreach (MeasureType val in values)
            {
                this.supplyMeasureType.Items.Add(new ListItem(val.GetDescription(), ((int)val).ToString()));
            }
        }
    }
}